home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / 16550.zip / IFIFO.C < prev    next >
Text File  |  1991-07-20  |  15KB  |  355 lines

  1. /* ififo.c     11/4/88    Louis Shay
  2.    This function is used to test basic FIFO functions of a NS16550A
  3.    or compatible UART channel at the system base address " int  ubase ". 
  4.    This address must be defined in the calling program.
  5.    Program requirements.
  6.  
  7.      1. #include <stdio.h>
  8.     #include <conio.h>
  9.     #include "ns16550a.h" must be in the main() source file.
  10.      2. Integer variables ubase and fatal_error must be declared as 
  11.         global values in the main() source program.
  12.      3. The  caller must set ubase to the device's base address before
  13.         calling ififo().
  14.      4. This program assumes basic 450-mode functionality, therefore
  15.         i450() should first be run and the fatal_error flag clear before
  16.         calling ififo(). The calling sequence in main() should be:
  17.  
  18.     1. Call i450()       - this tests basic functionality
  19.     2. IF ( fatal_error == 0 )
  20.               call ififo()
  21.            ELSE 
  22.               quit testing this UART channel.
  23.  
  24.    Hardware Requirements:
  25.       1. The UART I/O input pins SIN, CTS, DCD, DSR, RI, must
  26.          be pulled high and not driven by external sources during
  27.          this test, otherwise false errors may be generated.
  28.  
  29.    Error messages printed will be in the form " Error (n)...", where 
  30.    n refers to the section of this source program.               
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <conio.h>
  35. #include "ns16550a.h"
  36.  
  37. #define TIMEOUT 10000
  38.  
  39. int ififo()
  40. {
  41.   extern int ubase, fatal_error;
  42.   int rbrval, iirval, lsrval, tx_data = 0, rx_data = 0;
  43.   int error_count = 0, count_a, count_b, trigger, x=0;
  44.  
  45. /* 0. start test */
  46.   printf("\nNS16550A FIFO functions test...\n");
  47.  
  48. /* 1. Initialize FIFO mode and check FIFO init. state */
  49.  
  50.   wrLCR( 0x80 );                /* LCR = 80h, set DLAB */
  51.   wrDLL( 0x9c );                /* DLL, 9600 baud @ 1.8MHz input */
  52.   wrDLM( 0 );
  53.   wrLCR( 0x03 );                /* LCR: 8 data, 1 stop, no pty. */
  54.   wrMCR( 0x10 );                /* MCR: internal loopback mode */
  55.   wrFCR( 0xcf );                /* FCR: fifo mode 1, reset, trigger=14 */
  56.   wrIER( 0x0f );                /* IER: interrupts on */
  57.  
  58.   iirval = rdIIR();             /* check ID bits */
  59.   lsrval = rdLSR();             /* check THRE and DR */
  60.   rbrval = rdRBR();             /* check rbr = 00h */
  61.  
  62.   if( ( iirval & 0xc0 ) != 0xc0 ) { /* no ID bits - fatal error */
  63.     printf(" Error (1)..FIFO ID bits not set! IIR = %2x\n", iirval );
  64.     error_count += 1;
  65.     goto ABORT;
  66.   }
  67.   if( lsrval != 0x60 ) {
  68.     printf(" Error (1)..FIFO init. error : LSR = %2x\n", lsrval );
  69.     error_count += 1;
  70.   }
  71.   if( rbrval != 0 ) {
  72.     printf(" Error (1)..FIFO init. error : RBR = %2x\n", rbrval );
  73.     error_count += 1;
  74.   }
  75.   if( ( iirval & 0x0f ) != 2 ) {
  76.     printf(" Error (1)..FIFO init. error : IIR = %2x\n", iirval );
  77.     error_count += 1;
  78.   }
  79.  
  80.  
  81. /* 2. Test basic FIFO functions - loop a character */
  82.     
  83.   wrTHR( 0x55 );                        /* send a byte */
  84.   while( !( rdLSR() & 0x40 )) ;         /* poll LSR until TEMT is set */
  85.   lsrval = rdLSR();                     /* test for rx data and lsr clean */
  86.   rbrval = rdRBR();
  87.   if(((lsrval & 0x01 ) == 0 )||(( lsrval & 0x1e ) != 0 )||( rbrval != 0x55 ))
  88.   { /* if DR = 0, or OE/PE/FE/BI set, or rbr not 55h, then error */
  89.     printf(" Error (2)..Tx / Rx 1st read: LSR = %2x RBR = %2x (55H)\n",
  90.              lsrval, rbrval );
  91.     error_count += 1;
  92.   }
  93.   lsrval = rdLSR();             /* test for FIFO empty condition - read again */
  94.   rbrval = rdRBR();
  95.   if((( lsrval & 0x01 ) == 1 )||(( lsrval & 0x9e ) != 0 )||( rbrval != 0x00 ))
  96.   { /* if DR = 1, or OE/PE/FE/BI/EIF set, or RBR not 00h, then error */
  97.     printf(" Error (2)..Tx / Rx 2nd read: LSR = %2x RBR = %2x (00H)\n",
  98.              lsrval, rbrval );
  99.     error_count += 1;
  100.   }
  101.  
  102.  
  103. /* 3. Test FIFO reset functions - FCR & LSR */
  104.  
  105.   for( count_a = 1 ; count_a <=  16 ; count_a++ )   /* fill tx FIFO */
  106.      wrTHR( count_a );
  107.  
  108.   wrFCR( 0xcd );                     /* reset tx fifo but not rx fifo */
  109.   lsrval = rdLSR();
  110.   if( ( lsrval & 0x20 ) == 0 ) { /* if reset, THRE = 1  */
  111.     printf(" Error (3)..Tx FIFO reset : LSR = %2x\n", lsrval );
  112.     error_count += 1;
  113.   }
  114.  
  115.   wrFCR( 0 );                   /* reinitialize fifo's */
  116.   wrFCR( 0xcf );                /* trigger=14, cleared, mode 1 */
  117.  
  118.   while ( !( rdLSR() & 0x40 )) ;        /* poll TEMT until set */
  119.   wrFCR( 0xcf );                        /* reset FIFO */
  120.   lsrval = rdLSR();                     /* read status */
  121.   rbrval = rdRBR();
  122.   if( (( lsrval & 0x01 ) == 1 ) || ( rbrval != 0 ) ) {
  123.     printf(" Error (3)..Rx FIFO reset : LSR = %2x RBR = %2x\n", lsrval,
  124.              rbrval );
  125.     error_count += 1;
  126.   }
  127.  
  128.  
  129. /* 4. Test FIFO-mode loop transfers 00 to ff (16 byte blocks) 
  130.        This section sends 16 blocks of 16 bytes each, and compares
  131.       receiver data to transmitted data. LSR values for each byte received
  132.        are also checked. At the end of each 16 bytes received, the RBR
  133.       is read a 17th time to check for a FIFO empty condition.*/
  134.  
  135.   wrLCR( 0x80 );        /* init. UART */
  136.   wrDLL( 0x0c );        /* 9600 baud */
  137.   wrDLM( 0 );
  138.   wrLCR( 0x0f );        /* LCR : 8 data, 2 stops, odd pty */
  139.   wrFCR( 0 );
  140.   wrFCR( 0xcf );        /* FCR : trigger=14, mode 1, cleared */
  141.   wrIER( 0 );           /* interrupts off */
  142.   (void)rdRBR();           /* clear registers */
  143.   (void)rdLSR();
  144.   (void)rdMSR();
  145.   tx_data = 0;        /* init tx data byte */
  146.   rx_data = 0;        /* init rx comparitor byte */
  147.  
  148.   /* loopback test loop 16 x 16 = 256 bytes sent */
  149.   for( count_a = 1 ; count_a <= 16 ; count_a++ ) {
  150.       (void)rdRBR();             /* dummy read */
  151.      for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
  152.     wrTHR( tx_data++ );      /* load tx FIFO with counter data */
  153.      }
  154.      while( !( rdLSR() & 0x40 )) ;      /* wait for TEMT set */
  155.      for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
  156.     lsrval = rdLSR();       /* check rx FIFO contents */
  157.     rbrval = rdRBR();
  158.     if( (( lsrval & 0x9f ) != 1 ) || ( rbrval != ( rx_data & 0xff )) )
  159.         { /* if DR = 0, or OE/PE/FE/BI/EIF set, or rbrval != Tx_data, then..*/
  160.           printf(" Error (4)..FIFO data: read=%d  LSR=%2x  RBR=%2x  TX=%2x\n",
  161.                    count_b, lsrval, rbrval, rx_data );
  162.           error_count += 1;
  163.         }
  164.         rx_data += 1;        /* increment comparator */
  165.      }
  166.      lsrval = rdLSR();          /* check for FIFOs empty */
  167.      rbrval = rdRBR();
  168.      if( ( lsrval != 0x60 ) || ( rbrval != 0 ) ) {
  169.        printf(" Error (4)..FIFO not empty: read=17  LSR=%2x  RBR=%2x\n",
  170.                 lsrval, rbrval );
  171.        error_count += 1;
  172.      }
  173.   }
  174.  
  175. /* 5. Test IIR / Rx FIFO trigger levels 
  176.        For each of the four trigger levels, this test will:
  177.        1. Fill the Rx FIFO to trigger - 1.
  178.           check for NO interrupt.
  179.        2. Send one byte. Reach receiver trigger level.
  180.           check for DR interrupt set.
  181.        3. Read a byte from RBR - drop below trigger level.
  182.           check for interrupt clear. */
  183.  
  184.   for( count_a = 0 ; count_a <= 3 ; count_a++ ) 
  185.   { /* test each of the four trigger levels for IIR set & reset */
  186.  
  187.      wrFCR( 0 );                /* reset FIFOs to char mode */
  188.      wrIER( 0 );                /* reset interrupts */
  189.      wrIER( 0x05 );             /* IER : enable RDAI, LSI */
  190.      while( !( rdLSR() & 0x40 )) ;      /* poll TEMT until set */
  191.      /* fill rx FIFO to 1 byte under trigger level */
  192.      switch( count_a ) {
  193.        case 0: wrFCR( 0x0f );           /* trigger = 1 */
  194.                trigger = 1;
  195.                break;            /* send 0 bytes */
  196.  
  197.        case 1: wrFCR( 0x4f );           /* trigger = 4 */
  198.                trigger = 4;
  199.            for( count_b = 1 ; count_b <= 3 ; count_b++ )
  200.           wrTHR( count_b );     /* send 3 bytes */
  201.                break;
  202.  
  203.        case 2: wrFCR( 0x8f );           /* trigger = 8 */
  204.                trigger = 8;
  205.                for( count_b = 1 ; count_b <= 7 ; count_b++ )
  206.           wrTHR( count_b );     /* send 7 bytes */
  207.                break;
  208.  
  209.        case 3: wrFCR( 0xcf );           /* trigger = 14 */
  210.                trigger = 14;
  211.                for( count_b = 1 ; count_b <= 13 ; count_b++ )
  212.           wrTHR( count_b );     /* send 13 bytes */
  213.                break;
  214.      }
  215.      while( ( rdLSR() & 0x60 ) != 0x60 ) ;      /* wait for TEMT */
  216.      iirval = rdIIR();                          /* check for no Intr. */
  217.      lsrval = rdLSR();                          /* read status */
  218.      if( iirval != 0xc1 ) {     /* intr should not yet be set */
  219.        printf(" Error (5)..IIR set below trigger: IIR=%2x LSR=%2x T=%d\n",
  220.                 iirval, lsrval, trigger );
  221.        error_count += 1;
  222.      }
  223.      wrTHR( 0x55 );                             /* send a byte - trigger INTR. */
  224.      while( ( rdLSR() & 0x60 ) != 0x60 ) ;      /* wait for TEMT */
  225.      iirval = rdIIR();
  226.      lsrval = rdLSR();
  227.      if( iirval != 0xc4 )  {        /* INTR should trigger here */
  228.        printf(" Error (5)..Trigger failed: IIR=%2x LSR=%2x T=%d\n",
  229.                 iirval, lsrval, trigger );
  230.        error_count += 1;
  231.      }
  232.      rbrval = rdRBR();                  /* read a byte - clear interrupt. */
  233.      iirval = rdIIR();                  /* check IIR register */
  234.      lsrval = rdLSR();
  235.      if( iirval != 0xc1 )  {    /* interrupt should be cleared here */
  236.        printf(" Error (5)..INTR not cleared: IIR=%2x LSR=%2x T=%d\n",
  237.                 iirval, lsrval, trigger );
  238.        error_count += 1;
  239.      }
  240.   }
  241.          
  242.  
  243. /* 6. Test Reciever Data Timeout interrupt function. 
  244.        This test will load one byte into the Rx FIFO via loopback. Then
  245.       four bytes will be transmitted when NOT in loopback so that the
  246.       receiver will be inactive for four character times. The Rx FIFO
  247.       timeout interrupt should occur at this point. */
  248.  
  249.   /* initialize */
  250.   wrLCR( 0x80 );                /* LCR: set baud */
  251.   wrDLL( 0x4e );                /* 9600 w/ 1.8 MHz clock */
  252.   wrDLM( 0 );
  253.   wrLCR( 0x03 );                /* LCR: 8 data, 1 stop, no pty */
  254.   wrIER( 0 );                   /* interrupts off */
  255.   wrFCR( 0 );                   /* FIFO's off */
  256.   wrMCR( 0x10 );                /* internal loopback mode */
  257.   (void)rdRBR();                /* clear data buffer */
  258.   (void)rdLSR();                /* clear status */
  259.   (void)rdMSR();
  260.   wrIER( 0x01 );                /* enable RDAI */
  261.  
  262.   /* send a byte */
  263.   while( !( rdLSR() & 0x40 )) ;         /* wait for TEMT */
  264.   wrFCR( 0xcf );                        /* set FIFO mode 1, Trigger = 14 */
  265.   wrTHR( 0x55 );                        /* load 55H into tx FIFO */
  266.   while( !( rdLSR() & 0x01 )) ;         /* wait for DR set */
  267.   iirval = rdIIR();                     /* check intr status */
  268.   if( iirval != 0xc1 ) {  /* expecting no interrupt at this time */
  269.     printf(" Error (6).. illegal interrupt error: IIR = %2x  LSR = %2x\n",
  270.              iirval , lsrval );
  271.     error_count += 1;
  272.   }
  273.  
  274.   wrMCR( 0 );                           /* disable loopback mode */
  275.  
  276.   wrTHR( 0 );                           /* send five bytes */
  277.   wrTHR( 0 );
  278.   wrTHR( 0 );
  279.   wrTHR( 0 );
  280.   wrTHR( 0 );
  281.   /* at this point, the receiver will sit idle without taking in the
  282.      five characters that were sent. This should cause a timeout interrupt */
  283.  
  284.   while( !(( lsrval = rdLSR() ) & 0x40 )) ; /* wait for TEMT */
  285.   iirval = rdIIR();
  286.   if( iirval != 0xcc ) {    /* expecting Rx timeout interrupt */
  287.     printf(" Error (6)..Timeout interrupt failed: IIR = %2x  LSR = %2x\n",
  288.              iirval, lsrval );
  289.     error_count += 1;
  290.   }
  291.  
  292. /* 7. Test FIFO-mode LSR functions. This segment will exercise the 
  293.       BI, FE, EIF, and bits in FIFO mode. PE bit is not tested.*/
  294.  
  295.   /* initialize */
  296.   wrFCR( 0 );                   /* clear FCR */
  297.   wrMCR( 0x10 );                /* loop mode */
  298.   wrLCR( 0x03 );                /* 8 bit data */
  299.   wrIER( 0x04 );                /* enable LSI */
  300.  
  301.   /* Test EIF, BI, and FE - receive a byte, set break, watch LSR FIFO */
  302.   while( !( rdLSR() & 0x60 )) ; /* poll TEMT until empty */
  303.   wrFCR( 0xcf );                /* enable FIFO mode */
  304.   wrTHR( 0x55 );                /* send a byte around */
  305.   while( !( rdLSR() & 0x60 )) ; /* poll TEMT until empty */
  306.   wrTHR( 0 );                   /* load a 0 byte for timing purposes */
  307.   wrLCR ( 0x43 );               /* set a break */
  308.   while( !(( lsrval = rdLSR() ) &  0x40 )) ;    /* wait for TEMT */
  309.   iirval = rdIIR();             /* read IIR - should be c1H */
  310.   lsrval = rdLSR();             /* read LSR - should be e1H */
  311.   if( ( lsrval != 0xe1 ) || ( iirval != 0xc1 ) ) {
  312.     printf(" Error (7).. EIF test: IIR = %2x  LSR = %2x\n",
  313.              iirval, lsrval );
  314.     error_count += 1;
  315.   }
  316.   rbrval = rdRBR();             /* read RBR - error bits at top of FIFO */
  317.   iirval = rdIIR();             /* should cause LSI interrupt -- IIR = c6H */
  318.   lsrval = rdLSR();             /* LSR: BI, FE, EIF expected -- LSR = f9H */
  319.   if( ( lsrval != 0xf9 ) || ( iirval != 0xc6 ) ) {
  320.     printf(" Error (7)..BI/FE/EIF test: IIR = %2x  LSR = %2x\n",
  321.              iirval, lsrval );
  322.     error_count += 1;
  323.   }
  324.   iirval = rdIIR();             /* expecting IIR = c1H */
  325.   lsrval = rdLSR();             /* check if clear */
  326.   if( ( lsrval != 0x61 ) || ( iirval != 0xc1 ) )  {
  327.     printf(" Error (7)..IIR/LSR not cleared: IIR = %2x  LSR = %2x\n",
  328.              iirval, lsrval );
  329.     error_count += 1;
  330.   }  
  331.  
  332.   /* test OE bit in FIFO mode - load 16 bytes, check, load 1 more, check. */
  333.   wrFCR( 0 );                   /* init. */
  334.   wrLCR( 0x03 );                /* 8 data bits */
  335.   wrMCR( 0x10 );                /* loop mode */
  336.   wrFCR( 0xcf );                /* fifo's on, trigger = 14 */
  337.   wrIER( 0x04 );                /* enable LSI */
  338.   for( count_a = 1 ; count_a <= 16 ; count_a++ )  /* load 16 bytes */
  339.      wrTHR( count_a );
  340.   while( !( rdLSR() & 0x60 ));  /* wait for TEMT */
  341.   wrTHR( 0x55 ); /* load 17th byte - overrun FIFO */
  342.   while( !((rdIIR() & 0x0f) == 0x06) )
  343.     if (x++ > TIMEOUT)
  344.     {
  345.         printf("Error: OE interrupt never indicated");
  346.         break;
  347.     }
  348.  
  349.   goto END;
  350. ABORT:  printf(" -- fatal error -- test aborted.\n");
  351.     fatal_error = 1;
  352. END:    return( error_count );
  353. }
  354.                                                                                                
  355.